package com.ruoyi.common.utils;

import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest;
import com.github.binarywang.wxpay.bean.result.WxPayRefundResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.ruoyi.common.exception.CustomException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class WXPayUtil {

	/**
     * XML格式字符串转换为Map
     *
     * @param strXML XML字符串
     * @return XML数据转换后的Map
     * @throws Exception
     */
    public static Map<String, String> xmlToMap(String strXML) throws Exception {
        try {
            Map<String, String> data = new HashMap<String, String>();
            DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder();
            InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
            org.w3c.dom.Document doc = documentBuilder.parse(stream);
            doc.getDocumentElement().normalize();
            NodeList nodeList = doc.getDocumentElement().getChildNodes();
            for (int idx = 0; idx < nodeList.getLength(); ++idx) {
                Node node = nodeList.item(idx);
                if (node.getNodeType() == Node.ELEMENT_NODE) {
                    org.w3c.dom.Element element = (org.w3c.dom.Element) node;
                    data.put(element.getNodeName(), element.getTextContent());
                }
            }
            try {
                stream.close();
            } catch (Exception ex) {
                // do nothing
            }
            return data;
        } catch (Exception ex) {
            WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML);
            throw ex;
        }
    }
    /**
     * 日志
     * @return
     */
    public static Logger getLogger() {
        Logger logger = LoggerFactory.getLogger("wxpay java sdk");
        return logger;
    }
    



    /**
     * 生成 HMACSHA256
     * @param data 待处理数据
     * @param key 密钥
     * @return 加密结果
     * @throws Exception
     */
    public static String HMACSHA256(String data, String key) throws Exception {
        Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
        SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256");
        sha256_HMAC.init(secret_key);
        byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }
    
    /**
     * 生成 MD5
     *
     * @param data 待处理数据
     * @return MD5结果
     */
    public static String MD5(String data) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] array = md.digest(data.getBytes("UTF-8"));
        StringBuilder sb = new StringBuilder();
        for (byte item : array) {
            sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString().toUpperCase();
    }
    
  //通过xml 发给微信消息
  	public static String setXml(String return_code, String return_msg) {
  		SortedMap<String, String> parameters = new TreeMap<String, String>();
  		parameters.put("return_code", return_code);
  		parameters.put("return_msg", return_msg);
  		return "<xml><return_code><![CDATA[" + return_code + "]]>" +
  				"</return_code><return_msg><![CDATA[" + return_msg + "]]></return_msg></xml>";
  	}
  	/**
  	 * 微信退款
  	 * orderNo:退款订单号,totalFee:订单总金额,refundFee:需要退的金额
  	 */
  	public static WxPayRefundResult getRefundResult(WxPayService wxPayService,String out_trade_no,String totalFee,String refundFee){
  		System.out.println("发起微信退款："+out_trade_no);
  		//返回的结果
  		WxPayRefundResult result = null;
  		//orderNo+"id"+orderId
		WxPayRefundRequest wxPayRefundRequest=new WxPayRefundRequest();
		wxPayRefundRequest.setOutTradeNo(out_trade_no);
		wxPayRefundRequest.setOutRefundNo(out_trade_no);
		wxPayRefundRequest.setTotalFee(ToolUtil.yuanToFen(totalFee));
		wxPayRefundRequest.setRefundFee(ToolUtil.yuanToFen(refundFee));
		try {
			result=wxPayService.refund(wxPayRefundRequest);
		} catch (WxPayException e) {
			e.printStackTrace();
			throw new CustomException("系统错误!");
		}
  		return result;
  	} 
}
